package com.zhdl.network.service.impl;

import cn.hutool.core.util.HexUtil;
import com.project.command.instruction.bo.SingleInstruction;
import com.zhdl.common.util.IdUtil;
import com.zhdl.common.ytools.ByteHelper;
import com.zhdl.instruction.ExecuteInstructionService;
import com.zhdl.modules.prefiresys.web.request.CtrlSoundRequest;
import com.zhdl.modules.prefiresys.web.request.SetDetectorParamRequest;
import com.zhdl.modules.prefiresys.web.request.SetFactoryParamRequest;
import com.zhdl.modules.prefiresys.web.response.TcpSerialResp;
import com.zhdl.modules.prefiresys.web.service.PortTcpServiceImpl;
import com.zhdl.network.prefiretcp.after.PrefireTcpAfterService;
import com.zhdl.network.prefiretcp.analysis.PreFireTcpAnalysisImpl;
import com.zhdl.network.prefiretcp.before.MemDevice;
import com.zhdl.network.servertcp.DuplexProtocolSendService;
import com.zhdl.network.service.FireService;
import com.zhdl.network.service.conf.PortConf;
import com.zhdl.network.service.dto.SingleParaInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static com.project.command.instruction.strategy.abs.AbsDic.INSTRUCTION_DEFAULT_HEX;
import static com.zhdl.network.prefirertu.after.UpsAfterService.UPS_AFTER_SERVICE;
import static com.zhdl.network.prefirertu.analysis.UpsAnalysis.UPS_ANALYSIS;

@Slf4j
@Service
public class FireServiceImpl implements FireService {
    @Resource
    private ExecuteInstructionService instructionService;

    @Resource
    private PortConf portConf;

    @Resource
    private PortTcpServiceImpl portTcpService;

    /**
     * 发送指令 - 灵活
     *
     * @param cmd 指令
     */
//    @Override
//    public void sendCmd(String cmd, String port) {
//        SingleInstruction instruction = new SingleInstruction();
//        instruction.setInstructionId(IdUtil.getUUID_8());
//        instruction.setInstruction(cmd);
//        log.info("---------------》"+cmd);
//        instruction.setBeforeInstructionName(INSTRUCTION_DEFAULT_HEX);
//        //默认使用com.zhdl.instruction.strategy包下后置策略
//        instruction.setAfterInstructionName(PrefireTcpAfterService.PREFIRE_TCP_AFTER_SERVICE);
//        //设置协议  数据来源 : protocols 表
//        instruction.setProtocols(PreFireTcpAnalysisImpl.PREFIRE_TCP_ANALYSIS);
//
//        /* list.for getPortKey 发送数据库对应数量 */
//        //客户端通信地址, 串口为数字, 网口为ip+端口
//        // 数据来源 : port_comm 或 port_socket 表
//        String tcpPortFire = portConf.getTcpPortFireOne();
//        String[] split = tcpPortFire.split(":");
//        String s = split[0];
//        instruction.setPortKey(s + ":" + port);
////        instruction.setPortKey("192.168.0.111:" + port);
//        instructionService.perform(instruction);
//    }

    @Override
    public void sendCmd(String cmd,String port) {
//        SingleInstruction instruction = new SingleInstruction();
//        instruction.setInstructionId(IdUtil.getUUID_8());
//        //设置要发送的指令字符串
//        instruction.setInstruction(cmd);
//        instruction.setBeforeInstructionName(INSTRUCTION_DEFAULT_HEX);
//        //默认使用com.zhdl.instruction.strategy包下后置策略
//        instruction.setAfterInstructionName(UPS_AFTER_SERVICE);
//        //客户端通信地址, 串口为数字, 网口为ip+端口       数据来源 : port_comm 或 port_socket 表
//        instruction.setPortKey("10");
//        //设置协议  数据来源 : protocols 表
//        instruction.setProtocols(UPS_ANALYSIS);
//        instructionService.perform(instruction);
        log.info("----------->" + port);
//        DuplexProtocolSendService.sendCmd(port,cmd);
        DuplexProtocolSendService.sendCmdToAll(port,cmd);
    }

    public List<String> getPort(){
        List<TcpSerialResp> allTcpList = portTcpService.getAllTcpList();
        List<String> ipList = new ArrayList<>();
        for (TcpSerialResp tcpSerialResp : allTcpList) {
            ipList.add(tcpSerialResp.getServerPort());
        }
        return ipList;
    }

    public String getPortByAddressId(short address){
        switch (address){
            case 1 ->{
                return "172.16.2.34";
            }
            case 2 ->{
                return "10125";
            }
            case 3 ->{
                return "10127";
            }
            case 4 ->{
                return "10129";
            }
        }
        return "";
    }

    /**
     * 获取探测器参数
     */
    @Override
    public void getDetectorParam(MemDevice memDevice) {

        List<Byte> paramList = new ArrayList<>();

        byte bt;

        // 0x13-0x16
        bt = (byte) 0x13;
        for (int i = 0; i < 4; i++)
            paramList.add(bt++);

        // 0xA0-0xA9
        bt = (byte) 0xA0;
        for (int i = 0; i < 10; i++)
            paramList.add(bt++);

        // 0xAC-0xBF
        bt = (byte) 0xAC;
        for (int i = 0; i < 20; i++)
            paramList.add(bt++);

        byte[] bytes = ByteHelper.byteListToByteArray(paramList);
        try {
            byte[] bytes1 = memDevice.getPkg().GetPara(bytes);
            String portByAddressId = getPortByAddressId(memDevice.getDetectorAddr());
            log.info("获取厂家参数 allPara 97 --------> {}",HexUtil.encodeHexStr(bytes1));
            sendCmd(HexUtil.encodeHexStr(bytes1), portByAddressId);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * 设置探测器参数
     */
    @Override
    public void setDetectorParam(SetDetectorParamRequest setDetectorParamRequest, MemDevice memDevice) {
        try {
            byte[] bytes = memDevice.getPkg().setDetectorPara(setDetectorParamRequest);
            String portByAddressId = getPortByAddressId(memDevice.getDetectorAddr());
            sendCmd(HexUtil.encodeHexStr(bytes), portByAddressId);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取探厂家参数
     */
    public void getFactoryParam(MemDevice memDevice) {

        List<Byte> paramList = new ArrayList<>();
        byte bt;

        // 0xE0-0x16
        bt = (byte) 0xE0;

        for (int i = 0; i < 12; i++)
            paramList.add(bt++);

        byte[] bytes = ByteHelper.byteListToByteArray(paramList);

        try {
            byte[] bytes1 = memDevice.getPkg().GetPara(bytes);
            String portByAddressId = getPortByAddressId(memDevice.getDetectorAddr());
            sendCmd(HexUtil.encodeHexStr(bytes1), portByAddressId);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * 设置厂家参数
     *
     * @param request
     * @param memDevice
     */
    @Override
    public void setFactoryParam(SetFactoryParamRequest request, MemDevice memDevice) {
        try {
            byte[] bytes = memDevice.getPkg().setFactoryPara(request);
            String portByAddressId = getPortByAddressId(memDevice.getDetectorAddr());
            sendCmd(HexUtil.encodeHexStr(bytes), portByAddressId);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取相机数据
     *
     * @return
     */
    @Override
    public void GeneralParamMonitor(MemDevice memDevice) {
        try {
            byte[] bytes = memDevice.getPkg().GeneralParamMonitor();
            String portByAddressId = getPortByAddressId(memDevice.getDetectorAddr());
//            sendCmd(HexUtil.encodeHexStr(bytes), portByAddressId);
            log.info("send++++++++++"+Arrays.toString(bytes));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 设置消除警报
     */
    @Override
    public void setClearAlarm(MemDevice memDevice) {

        byte paramNo = 0x12;
        byte bt = ByteHelper.bitString2Byte("00000001");
        List<SingleParaInfo> paramList = new ArrayList<>();

        paramList.add(new SingleParaInfo(paramNo, new byte[]{bt}));

        try {
            byte[] bytes = memDevice.getPkg().SetPara(paramList);
            String portByAddressId = getPortByAddressId(memDevice.getDetectorAddr());
            sendCmd(HexUtil.encodeHexStr(bytes), portByAddressId);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 设置静音或者取消静音
     *
     * @param memDevice
     */
    @Override
    public void setCtrlSound(MemDevice memDevice, CtrlSoundRequest request) {
        List<SingleParaInfo> paramList = new ArrayList<>();
        SingleParaInfo paraInfo = new SingleParaInfo();
        byte paramNo = 0x1B;
        paraInfo.setId(paramNo);
        paraInfo.setData(new byte[]{request.isSoundEnable() ? (byte) 0x01 : (byte) 0x00});
        paramList.add(paraInfo);

        try {
            byte[] bytes = memDevice.getPkg().SetPara(paramList);
            String portByAddressId = getPortByAddressId(memDevice.getDetectorAddr());
            sendCmd(HexUtil.encodeHexStr(bytes), portByAddressId);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * 设置静音或者取消静音 通知火前实现
     *
     * @param memDevice
     * @param request
     */
    @Override
    public void setBeforeFireCtrlSound(MemDevice memDevice, CtrlSoundRequest request) {
        List<SingleParaInfo> paramList = new ArrayList<>();
        SingleParaInfo paraInfo = new SingleParaInfo();
        byte paramNo = 0x1B;
        paraInfo.setId(paramNo);
        paraInfo.setData(new byte[]{request.isSoundEnable() ? (byte) 0x01 : (byte) 0x00});
        paramList.add(paraInfo);

        try {
            byte[] bytes = memDevice.getPkg().SetPara(paramList);
            String portByAddressId = getPortByAddressId(memDevice.getDetectorAddr());
            sendCmd(HexUtil.encodeHexStr(bytes), portByAddressId);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 关闭蜂鸣器 打开报警灯
     *
     * @param memDevice
     * @param isSound
     */
    @Override
    public void setCameraCtrlSound(MemDevice memDevice, boolean isSound) {
        List<SingleParaInfo> paramList = new ArrayList<>();
        SingleParaInfo paraInfo = new SingleParaInfo();

        byte paramNo = 0x2C;
        paraInfo.setId(paramNo);
        paraInfo.setData(new byte[]{isSound ? (byte) 0x01 : (byte) 0x00});
        paramList.add(paraInfo);

        try {
            byte[] bytes = memDevice.getPkg().SetPara(paramList);
            String portByAddressId = getPortByAddressId(memDevice.getDetectorAddr());
            sendCmd(HexUtil.encodeHexStr(bytes), portByAddressId);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}
